package com.ankiang.treeprint.model;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ankiang.treeprint.lib.Pinyin;

import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;

public class TRItemNode extends JSONObject implements Comparable, Serializable {

    private int id;                       // id，用于索引
    private String userid;                // 用户id
    private int group;                    // 分组，区分不同分组

    private int relative;                 // 关系类型
    private int mid;                      // 母id
    private int fid;                      // 父id
    private String name;                  // 姓名
    private String nickname;              // 昵称
    private String callname;              // 称呼
    private int order;                    // 排行
    private char sex;                     // 性别，F/M, 女/男
    private String image;                 // 图片，url格式
    private String bornDateSun;           // 阳历出生年月，未知状态为0，YYYYMMDD格式, YYYY未知状态为0000
    private String bornDateMoon;          // 农历出生年月，未知状态为0，YYYYMMDD格式
    private int state;                    // 0-正常态，-1为虚拟生成态
    private String inserttime;            // 插入时间
    private String updatetime;            // 更新时间
    private String viewtime;              // 查看时间
    private String remark;                // 备注信息


    private String pinyinName;                  // 姓名
    private String pinyinNickname;              // 昵称
    private String pinyinCallname;              // 称呼

    private String pinyinCapName;                  // 姓名
    private String pinyinCapNickname;              // 昵称
    private String pinyinCapCallname;              // 称呼

    // 用于计算布局
    private int top;
    private int left;
    private int bottom;
    private int right;


    private int column;                   // 列，从0开始
    private int row;                      // 行，从0开始
    private int color = 0;                // 着色

    public static TRItemNode convert(JSONObject obj) {
        TRItemNode item = new TRItemNode();
        if (obj.containsKey("id")) {
            int id = obj.getInteger("id");
            item.setId(id);
        }

        if (obj.containsKey("fid")) {
            int fid = obj.getInteger("fid");
            item.setFid(fid);
        }

        if (obj.containsKey("mid")) {
            int mid = obj.getInteger("mid");
            item.setMid(mid);
        }

        if (obj.containsKey("userid")) {
            String userid = obj.getString("userid");
            item.setUserid(userid);
        }

        if (obj.containsKey("state")) {
            int state = obj.getInteger("state");
            item.setState(state);
        }

        if (obj.containsKey("image")) {
            String image = obj.getString("image");
            item.setImage(image);
        }

        if (obj.containsKey("remark")) {
            String remark = obj.getString("remark");
            item.setRemark(remark);
        }

        if (obj.containsKey("order")) {
            int order = obj.getInteger("order");
            item.setOrder(order);
        }

        if (obj.containsKey("callname")) {
            String callname = obj.getString("callname");
            item.setCallname(callname);
        }

        if (obj.containsKey("nickname")) {
            String nickname = obj.getString("nickname");
            item.setNickname(nickname);
        }

        if (obj.containsKey("name")) {
            String name = obj.getString("name");
            item.setName(name);
        }

        if (obj.containsKey("bornDateSun")) {
            String bornDateSun = obj.getString("bornDateSun");
            item.setBornDateSun(bornDateSun);
        }

        if (obj.containsKey("bornDateMoon")) {
            String bornDateMoon = obj.getString("bornDateMoon");
            item.setBornDateMoon(bornDateMoon);
        }

        if (obj.containsKey("sex")) {
            char sex = obj.getString("sex").charAt(0);
            item.setSex(sex);
        }

        if (obj.containsKey("inserttime")) {
            String inserttime = obj.getString("inserttime");
            item.setInserttime(inserttime);
        }

        if (obj.containsKey("updatetime")) {
            String updatetime = obj.getString("updatetime");
            item.setUpdatetime(updatetime);
        }

        if (obj.containsKey("viewtime")) {
            String viewtime = obj.getString("viewtime");
            item.setViewtime(viewtime);
        }

        if (obj.containsKey("row")) {
            int row = obj.getInteger("row");
            item.setRow(row);
        }

        if (obj.containsKey("color")) {
            int color = obj.getInteger("color");
            item.setColor(color);
        }

        if (obj.containsKey("column")) {
            int column = obj.getInteger("column");
            item.setColumn(column);
        }

        if (obj.containsKey("left")) {
            int left = obj.getInteger("left");
            item.setLeft(left);
        }

        if (obj.containsKey("right")) {
            int right = obj.getInteger("right");
            item.setRight(right);
        }

        if (obj.containsKey("top")) {
            int top = obj.getInteger("top");
            item.setTop(top);
        }

        if (obj.containsKey("bottom")) {
            int bottom = obj.getInteger("bottom");
            item.setBottom(bottom);
        }

        return item;
    }

    private void setViewtime(String viewtime) {
        this.viewtime = viewtime;
    }

    // 查找
    public boolean match(String kw) {
        if (kw == null || kw.equals("")) {
            return true;
        }
        if (callname.indexOf(kw) != -1 || nickname.indexOf(kw) != -1
                || name.indexOf(kw) != -1) {
            return true;
        }

        genPinyin();
        kw = kw.toLowerCase();
        if (pinyinCallname.indexOf(kw) != -1
                || pinyinNickname.indexOf(kw) != -1
                || pinyinName.indexOf(kw) != -1


                // 首字母拼音
                || pinyinCapCallname.indexOf(kw) != -1
                || pinyinCapNickname.indexOf(kw) != -1
                || pinyinCapName.indexOf(kw) != -1
                ) {
            return true;
        }


        return false;
    }

    private void genPinyin() {

        // 如果没有保存过拼音，生成拼音
        if (pinyinCallname == null || "".equals(pinyinCallname)) {
            pinyinCallname = Pinyin.hanziToPinyin(callname);
            pinyinName = Pinyin.hanziToPinyin(name);
            pinyinNickname = Pinyin.hanziToPinyin(nickname);

            //拼音首字母
            pinyinCapCallname = Pinyin.extractUCChar(pinyinCallname).toLowerCase();
            pinyinCapName = Pinyin.extractUCChar(pinyinName).toLowerCase();
            pinyinCapNickname = Pinyin.extractUCChar(pinyinNickname).toLowerCase();

            pinyinCallname = pinyinCallname.toLowerCase();
            pinyinName = pinyinName.toLowerCase();
            pinyinNickname = pinyinNickname.toLowerCase();
        }

    }

    public String toJSONString() {
        String s = JSON.toJSONString(this);
        JSONObject tmp = JSON.parseObject(s);
//        tmp.put("top", this.top);
//        tmp.put("left", this.left);
//        tmp.put("bottom", this.bottom);
//        tmp.put("right", this.right);

        s = JSON.toJSONString(tmp, true);
        return s;
    }

    public String getPureBornDateMoon() {
        return this.bornDateMoon;
    }

    public boolean isValidBornDateMoon(String s) {

        return false;
    }

    public void refreshViewtime() {
        String now = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        this.viewtime = now;
    }

    public void refreshUpdatetime() {
        String now = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        this.updatetime = now;
    }


    public static class Status {
        // 正常状态，默认
        public static int NORMAL = 0;
        // 选中状态，会有特殊颜色标识
        public static int FOCUSED = 1;
    }


    public int getId() {
        return id;
    }

    public void setId(int id) {
        super.put("id", id);
        this.id = id;
    }

    public String getUserid() {
        return super.getString("userid");
    }

    public void setUserid(String userid) {
        super.put("userid", userid);
        this.userid = userid;
    }

    public int getGroup() {
        return super.getIntValue("group");
    }

    public void setGroup(int group) {
        super.put("group", group);
        this.group = group;
    }

    public int getRelative() {
        return super.getIntValue("relative");
    }

    public void setRelative(int relative) {
        this.relative = relative;
        super.put("relative", relative);
    }

    public int getMid() {
        return super.getIntValue("mid");
    }

    public void setMid(int mid) {
        super.put("mid", mid);
        this.mid = mid;
    }

    public int getFid() {
        return super.getIntValue("fid");
    }

    public void setFid(int fid) {
        this.fid = fid;
        super.put("fid", fid);
    }

    public String getName() {
        return super.getString("name");
    }

    public void setName(String name) {
        this.name = name;
        super.put("name", name);
    }

    public String getNickname() {
        return super.getString("nickname");
    }

    public void setNickname(String nickname) {
        this.nickname = nickname;
        super.put("nickname", nickname);
    }

    public int getTop() {
        return top;
    }

    public void setTop(int top) {
        this.top = top;
        super.put("top", top);
    }

    public int getLeft() {
        return left;
    }

    public void setLeft(int left) {
        this.left = left;
        super.put("left", left);
    }

    public int getBottom() {
        return bottom;
    }

    public void setBottom(int bottom) {
        this.bottom = bottom;
        super.put("bottom", bottom);
    }

    public int getRight() {
        return right;
    }

    public void setRight(int right) {
        this.right = right;
        super.put("right", right);
    }

    public String getCallname() {
        return super.getString("callname");
    }

    public String getPinyinName() {
        genPinyin();
        return pinyinName;
    }

    public void setCallname(String callname) {
        this.callname = callname;
        super.put("callname", callname);
    }

    public int getOrder() {
        return super.getIntValue("order");
    }

    public void setOrder(int order) {
        this.order = order;
        super.put("order", order);
    }

    public char getSex() {
        String s = super.getString("sex");
        if (s == null || s.isEmpty()) {
            return ' ';
        }
        return s.charAt(0);
    }

    public void setSex(char sex) {
        this.sex = sex;
        super.put("sex", sex);
    }

    public String getImage() {
        return super.getString("image");
    }

    public void setImage(String image) {
        this.image = image;
        super.put("image", image);
    }

    public String getBornDateSun() {
        String s = super.getString("bornDateSun");
        if (s == null) {
            s = getNone();
        }

        if (s.equals(getNone())) {
            return getNone();
        }

        return s;
    }

    // 无数据时的显示
    public static String getNone() {
        return "待设置";
    }


    public void setBornDateSun(String bornDateSun) {
        this.bornDateSun = bornDateSun;
        super.put("bornDateSun", bornDateSun);
    }

    public String getBornDateMoon() {

        String s = super.getString("bornDateMoon");
        if (s == null) {
            s = getNone();
        }

        if (s.equals(getNone())) {
            return getNone();
        }

        HashMap<String, String> mapMonth = new HashMap<String, String>();
        mapMonth.put("01", "正月");
        mapMonth.put("02", "二月");
        mapMonth.put("03", "三月");
        mapMonth.put("04", "四月");
        mapMonth.put("05", "五月");
        mapMonth.put("06", "六月");
        mapMonth.put("07", "七月");
        mapMonth.put("08", "八月");
        mapMonth.put("09", "九月");
        mapMonth.put("10", "十月");
        mapMonth.put("11", "十一月");
        mapMonth.put("12", "腊月");


        HashMap<String, String> mapDay = new HashMap<String, String>();
        mapDay.put("01", "初一");
        mapDay.put("02", "初二");
        mapDay.put("03", "初三");
        mapDay.put("04", "初四");
        mapDay.put("05", "初五");
        mapDay.put("06", "初六");
        mapDay.put("07", "初七");
        mapDay.put("08", "初八");
        mapDay.put("09", "初九");
        mapDay.put("10", "初十");
        mapDay.put("11", "十一");
        mapDay.put("12", "十二");
        mapDay.put("13", "十三");
        mapDay.put("14", "十四");
        mapDay.put("15", "十五");
        mapDay.put("16", "十六");
        mapDay.put("17", "十七");
        mapDay.put("18", "十八");
        mapDay.put("19", "十九");
        mapDay.put("20", "二十");
        mapDay.put("21", "廿一");
        mapDay.put("22", "廿二");
        mapDay.put("23", "廿三");
        mapDay.put("24", "廿四");
        mapDay.put("25", "廿五");
        mapDay.put("26", "廿六");
        mapDay.put("27", "廿七");
        mapDay.put("28", "廿八");
        mapDay.put("29", "廿九");
        mapDay.put("30", "三十");


        String[] spans = s.split("-");
        String r = "";
        if (spans.length > 0) {
            r += spans[0] + "年";
        }
        if (spans.length > 1) {
            String month = mapMonth.get(spans[1]);
            if (month != null) {
                r += month;
            }
        }
        if (spans.length > 2) {
            String day = mapDay.get(spans[2]);
            if (day != null) {
                r += day;
            }
        }
        return r;
    }

    public void setBornDateMoon(String bornDateMoon) {
        this.bornDateMoon = bornDateMoon;
        super.put("bornDateMoon", bornDateMoon);
    }

    public int getState() {
        return super.getIntValue("state");
    }

    public void setState(int state) {
        this.state = state;
        super.put("state", state);
    }

    public String getInserttime() {
        return super.getString("inserttime");
    }

    public void setInserttime(String inserttime) {
        this.inserttime = inserttime;
        super.put("inserttime", inserttime);
    }

    public String getViewtime() {
        return viewtime;
    }

    public String getUpdatetime() {
        return super.getString("updatetime");
    }

    public void setUpdatetime(String updatetime) {
        this.updatetime = updatetime;
        super.put("updatetime", updatetime);
    }

    public String getRemark() {
        return super.getString("remark");
    }

    public void setRemark(String remark) {
        this.remark = remark;
        super.put("remark", remark);
    }

    public int getColumn() {
        return super.getIntValue("column");
    }

    public void setColumn(int column) {
        this.column = column;
        super.put("column", column);
    }

    public int getRow() {
        return super.getIntValue("row");
    }

    public void setRow(int row) {
        this.row = row;
        super.put("row", row);
    }

    public int getColor() {
        return super.getIntValue("color");
    }

    public void setColor(int color) {
        this.color = color;
        super.put("color", color);
    }


    public String toString() {
        return this.callname;
    }

    public TRItemNode() {
        initDefault();
    }

    private void initDefault() {
        // todo

        String now = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());

        group = 0;

        relative = 0;
        mid = 0;
        fid = 0;
        name = getNone();
        nickname = getNone();
        callname = getNone();
        order = 99;
        sex = ' ';
        image = "";
        bornDateSun = getTimeNone();
        bornDateMoon = getTimeNone();
        state = 0;
        inserttime = now;
        updatetime = now;
        viewtime = now;
        remark = getNone();
        state = Status.NORMAL;

        column = 0;
        row = 0;
        color = 0;


        super.put("group", group);

        super.put("relative", relative);
        super.put("mid", mid);
        super.put("fid", fid);
        super.put("name", name);
        super.put("nickname", nickname);
        super.put("callname", callname);
        super.put("order", order);
        super.put("sex", sex);
        super.put("image", image);
        super.put("bornDateSun", bornDateSun);
        super.put("bornDateMoon", bornDateMoon);
        super.put("inserttime", inserttime);
        super.put("updatetime", updatetime);
        super.put("viewtime", viewtime);
        super.put("remark", remark);
        super.put("state", state);

        super.put("column", column);
        super.put("row", row);
        super.put("color", color);
    }

    private String getTimeNone() {
        return "0000-00-00 00:00:00";
    }


    @Override
    public int compareTo(Object o) {
        if (o == null) {
            return 1;
        }
        // order by fid, mid, order
        TRItemNode item = (TRItemNode) o;
        if (item.fid != this.fid) {
            return this.fid - item.fid;
        }
        if (item.mid != this.mid) {
            return this.mid - item.mid;
        }
        if (item.order != this.order) {
            return this.order - item.order;
        }
        if (item.id != this.id) {
            return this.id - item.id;
        }
        if (item.getCallname() != this.getCallname()) {
            if (this.getCallname() == null) {
                return 1;
            }
            return this.getCallname().compareTo(item.getCallname());
        }
        if (item.getSex() != this.getSex()) {
            return this.getSex() - item.getSex();
        }

        if (item.getBornDateMoon() != this.getBornDateMoon()) {
            if (this.getBornDateMoon() == null) {
                return 1;
            }
            return this.getBornDateMoon().compareTo(item.getBornDateMoon());
        }
        if (item.getBornDateSun() != this.getBornDateSun()) {
            if (this.getBornDateSun() == null) {
                return 1;
            }
            return this.getBornDateSun().compareTo(item.getBornDateSun());
        }
        if (item.getImage() != this.getImage()) {
            if (this.getImage() == null) {
                return 1;
            }
            return this.getImage().compareTo(item.getImage());
        }
        if (item.getNickname() != this.getNickname()) {
            if (this.getNickname() == null) {
                return 1;
            }
            return this.getNickname().compareTo(item.getNickname());
        }


        return 0;
    }

    public class Sex {
        public static final char COUPLE = '0';
        public static final char MALE = 'M';
        public static final char FEMALE = 'F';
        public static final char NEUTER = 'N';
        public static final char UNKONWN = ' ';
    }

    public static final char[] sexList = new char[]{
            Sex.COUPLE, Sex.MALE, Sex.FEMALE, Sex.NEUTER, Sex.UNKONWN
    };

    @Override
    public TRItemNode clone() {
        TRItemNode node;
        node = TRItemNode.convert(this);
        return node;
    }
}
